package sketch.specs;

import java.util.LinkedList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.internal.core.dom.NaiveASTFlattener;

import sketch.ast.ASTUtils;
import sketch.util.Checker;

public class MethodDumperAfterRemovingUnusedVars extends NaiveASTFlattener {
	
	/**
	 * This class dumps the method body with all unused variables removed
	 * */
	public final List<VariableDeclarationStatement> unusedVars;
	
	public final MethodDeclaration methodToProcess;
	
	public MethodDumperAfterRemovingUnusedVars(MethodDeclaration method) {
		UnusedVarDeclarationRemover remover = new UnusedVarDeclarationRemover(method.getBody(), true);
		methodToProcess = method;
		unusedVars = remover.getAllRemovableVarDeclarationStatements();
//		System.out.println("unused vars: " + unusedVars);
//		System.out.println(method);
	}
	
//	@Override
//	public boolean visit(VariableDeclarationStatement statement) {
//		if(this.unusedVars.contains(statement)) {
//			ASTNode parent = statement.getParent();
//			Checker.checkTrue(parent instanceof Block, "Currently only support parent is a block, but " +
//					" this parent type: " + parent.getClass());
//			Block parentBlock = (Block)parent;
//			parentBlock.statements().remove(statement);
//			
//			return false;
//		}
//		return super.visit(statement);
//	}
	
	@Override
	public boolean visit(Block block) {
		
		List<Statement> stmts = block.statements();
		List<Statement> removable = new LinkedList<Statement>();
		for(Statement stmt : stmts) {
			if(this.unusedVars.contains(stmt)) {
				removable.add(stmt);
			}
		}
		
		if(removable.isEmpty()) {
			return super.visit(block);
		} else {
			block.statements().removeAll(removable);
			return super.visit(block);
		}
	}
	
	public String dumpMethodWithUnusedVarRemoved() {
		this.visit(methodToProcess);
		String result = this.getResult();
		return result;
		
	}
	
	public MethodDeclaration getUnusedVarRemovedMethod() {
		this.visit(this.methodToProcess);
		return this.methodToProcess;
	}
}
